package com.base_data_handler.utils.ftp;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.SocketException;
import java.util.Properties;
import java.util.StringTokenizer;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;

public class FtpUtil {
	  private static Logger logger = Logger.getLogger(FtpUtil.class);  
	  static FTPClient ftpClient = null;  
	    /** 
	     * 去 服务器的FTP路径下 上读取文件 
	     *  
	     * @param ftpUserName 
	     * @param ftpPassword 
	     * @param ftpPath 
	     * @param FTPServer 
	     * @return 
	     */  
	    public static String readConfigFileForFTP(String ftpUserName, String ftpPassword,  
	            String ftpPath, String ftpHost, int ftpPort, String fileName) {  
	        StringBuffer resultBuffer = new StringBuffer();  
	        FileInputStream inFile = null;  
	        InputStream in = null;  
	        logger.info("开始读取绝对路径" + ftpPath + "文件!");  
	        try {  
	            ftpClient = getFTPClient(ftpHost, ftpPassword, ftpUserName,  
	                    ftpPort);  
	            ftpClient.setControlEncoding("UTF-8"); // 中文支持  
	            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);  
	            ftpClient.enterLocalPassiveMode();  
	            ftpClient.changeWorkingDirectory(ftpPath);  
	            in = ftpClient.retrieveFileStream(fileName);  
	        } catch (FileNotFoundException e) {  
	            logger.error("没有找到" + ftpPath + "文件");  
	            e.printStackTrace();  
	            return "下载配置文件失败，请联系管理员.";  
	        } catch (SocketException e) {  
	            logger.error("连接FTP失败.");  
	            e.printStackTrace();  
	        } catch (IOException e) {  
	            e.printStackTrace();  
	            logger.error("文件读取错误。");  
	            e.printStackTrace();  
	            return "配置文件读取失败，请联系管理员.";  
	        }  
	        if (in != null) {  
	            BufferedReader br = new BufferedReader(new InputStreamReader(in));  
	            String data = null;  
	            try {  
	                while ((data = br.readLine()) != null) {  
	                    resultBuffer.append(data + "\n");  
	                }  
	            } catch (IOException e) {  
	                logger.error("文件读取错误。");  
	                e.printStackTrace();  
	                return "配置文件读取失败，请联系管理员.";  
	            }finally{  
	                try {  
	                    ftpClient.disconnect();  
	                } catch (IOException e) {  
	                    e.printStackTrace();  
	                }  
	            }  
	        }else{  
	            logger.error("in为空，不能读取。");  
	            return "配置文件读取失败，请联系管理员.";  
	        }  
	        return resultBuffer.toString();  
	    }  
	    
	    
	      
	      
	    /** 
	     * 获取FTPClient对象 
	     * @param ftpHost FTP主机服务器 
	     * @param ftpPassword FTP 登录密码 
	     * @param ftpUserName FTP登录用户名 
	     * @param ftpPort FTP端口 默认为21 
	     * @return 
	     */  
	    public static FTPClient getFTPClient(String ftpHost, String ftpPassword,  
	            String ftpUserName, int ftpPort) {  
	        try {  
	            ftpClient = new FTPClient();  
	            ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器  
	            ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器  
	            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {  
	                logger.info("未连接到FTP，用户名或密码错误。");  
	                ftpClient.disconnect();  
	            } else {  
	                logger.info("FTP连接成功。");  
	            }  
	        } catch (SocketException e) {  
	            e.printStackTrace();  
	            logger.info("FTP的IP地址可能错误，请正确配置。");  
	        } catch (IOException e) {  
	            e.printStackTrace();  
	            logger.info("FTP的端口错误,请正确配置。");  
	        }  
	        return ftpClient;  
	    }  
	    
	    /** 
	     * 本地上传文件到FTP服务器 
	     *  
	     * @param ftpPath 
	     *            远程文件路径FTP 
	     *            filePath本地需要上传的文件路径
	     * @throws IOException 
	     */  
	    public static boolean upload(String ftpPath, String ftpUserName, String ftpPassword,  
	            String ftpHost, int ftpPort, String filePath) {  
	        logger.info("开始上传文件到FTP.");  
	        boolean t = false;
	        try {  
	            ftpClient = getFTPClient(ftpHost, ftpPassword,  
	                    ftpUserName, ftpPort);  
	            // 设置PassiveMode传输  
	            ftpClient.enterLocalPassiveMode();  
	            // 设置以二进制流的方式传输  
	            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);  
	                // 对远程目录的处理  
	                File f = new File(filePath);  
	                InputStream in = new FileInputStream(f);  
	                
					//即可解决这个问题,如果上传不成功，修改编码后再试
	                boolean c = ftpClient.changeWorkingDirectory(ftpPath);
	                 t = ftpClient.storeFile(new String((f.getName()).getBytes("GBK"),"iso-8859-1"), in);  
		               if(t==true) {
		            	   in.close();    
		            	   System.out.println("上传文件" + filePath + "到FTP成功!");  
		            	    boolean i = f.delete();  
			                if(i){
			                	System.out.println("删除成功"+f.getAbsolutePath());
			                }else{
			                	System.out.println("删除失败"+f.getAbsolutePath());
			                }
		               }else{
		            	   System.out.println("上传文件" + filePath + "到FTP失败!"); 
			                logger.info("上传文件" + filePath + "到FTP成功!");  

		               } 
	        } catch (Exception e) {  
	            e.printStackTrace();  
	        }finally{  
	            try {  
	                ftpClient.disconnect();  
	            } catch (IOException e) {  
	                e.printStackTrace();  
	            }  
	        }  
	        return t;
	    }  
	    /** 
	     * 本地上传文件到FTP服务器 
	     *  
	     * @param ftpPath 
	     *            要上传的远程文件路径FTP 
	     *            filePath本地上传文件路径
	     *            saveFileName 本地文件名
	     * @throws IOException 
	     */  
	    public static boolean uploadLocalFile(String ftpPath, String ftpUserName, String ftpPassword,  
	            String ftpHost, int ftpPort, String filePath,  
	            String saveFileName) {  
	      
	        logger.info("开始上传文件到FTP.");  
	        try {  
	            ftpClient = getFTPClient(ftpHost, ftpPassword,  
	                    ftpUserName, ftpPort);  
	            // 设置PassiveMode传输  
//	            ftpClient.enterLocalPassiveMode(); 
	            ftpClient.enterLocalActiveMode();    //主动模式
	         // ftpClient.enterLocalPassiveMode(); 被动模式
	            // 设置以二进制流的方式传输  
	            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);  
	                File f = new File(filePath+"/"+saveFileName);  
	                InputStream in = new FileInputStream(f);  
	                
					//ftpClient.setControlEncoding("UTF-8");
					//并在创建目录或者storeFile时，将文件名转换编码方式即可，如：
					//ftpClient.storeFile(new String(fileName.getBytes("UTF-8"),"iso-8859-1"),fiStream);
					//或者：
					//ftpClient.makeDirectory(new String(pathName.getBytes("UTF-8"),"iso-8859-1"));
					//即可解决这个问题
	                boolean c = ftpClient.changeWorkingDirectory(ftpPath);
	                boolean t = ftpClient.storeFile(new String((f.getName()).getBytes("UTF-8"),"iso-8859-1"), in);  
		               if(t==true) {
		            	   in.close();    
		            	    System.out.println("上传文件" + saveFileName + "到FTP成功!");  
		            	    boolean i = f.delete();  
			                if(i){
			                	System.out.println("删除成功"+f.getAbsolutePath());
			                }else{
			                	System.out.println("删除失败"+f.getAbsolutePath());
			                }
		               }else{
		            	   System.out.println("上传文件" + saveFileName + "到FTP失败!"); 
			                logger.info("上传文件" + saveFileName + "到FTP成功!");  
		               }
		         
	               
	        } catch (Exception e) {  
	            e.printStackTrace(); 
	            return false;  
	        }finally{  
	            try {  
	                ftpClient.disconnect();  
	            } catch (IOException e) {  
	                e.printStackTrace();  
	            }  
	        }
			return true;  
	    }  
	    /** 
	     * 把配置文件先写到本地的一个文件中取 
	     *  
	     * @param ftpPath 
	     * @param str 
	     * @return 
	     */  
	    public static boolean write(String fileName, String fileContext,  
	            String writeTempFielPath) {  
	        try {  
	            logger.info("开始写配置文件");  
	            File f = new File(writeTempFielPath + "/" + fileName);  
	            if(!f.exists()){  
	                if(!f.createNewFile()){  
	                    logger.info("文件不存在，创建失败!");  
	                }  
	            }  
	            BufferedWriter bw = new BufferedWriter(new FileWriter(f, true));  
	            bw.write(fileContext.replaceAll("\n", "\r\n"));  
	            bw.flush();  
	            bw.close();  
	            return true;  
	        } catch (Exception e) {  
	            logger.error("写文件没有成功");  
	            e.printStackTrace();  
	            return false;  
	        }  
	    }  
	   

	    public static void main(String[] args) {  
	        int ftpPort = 0;  
	        String ftpUserName = "";  
	        String ftpPassword = "";  
	        String ftpHost = "";  
	        String ftpPath = "";  
	        String writeTempFielPath = "";  
	        try {  
	            InputStream in = FtpUtil.class.getClassLoader()  
	                    .getResourceAsStream("jdbc.properties");  
	            if (in == null) {  
	                logger.info("配置文件env.properties读取失败");  
	            } else {  
	                Properties properties = new Properties();  
	                properties.load(in);  
	                ftpUserName = properties.getProperty("ftp.user_name");  
	                ftpPassword = properties.getProperty("ftp.user_pass");  
	                ftpHost = properties.getProperty("ftp.host");  
	                ftpPort = Integer.valueOf(properties.getProperty("ftp.port"))  
	                        .intValue();  
	                ftpPath = "/yulin/zizhouxian/senlinfanghuo/";  
	                
	                writeTempFielPath = "C:/Users/Administrator/Desktop"; 
	                //读取ftp文件
//	                String result = FtpUtil.readConfigFileForFTP(ftpUserName, ftpPassword, ftpPath, ftpHost, ftpPort, "/radar/20170601154200001.png");  
	               //  System.out.println("读取配置文件结果为：" + result);  
	                  
	                //上传ftp文件
	                FtpUtil.upload(ftpPath, ftpUserName, ftpPassword, ftpHost, ftpPort,
	                		"C:/Users/Administrator/Desktop/王.jpg");  
	            }  
	        } catch (Exception e) {  
	            e.printStackTrace();  
	        }  
	    }  
	    
	    
	  //创建多层目录文件，如果有ftp服务器已存在该文件，则不创建，如果无，则创建
	    public static void createDirecroty(String remote) throws IOException {
	    	//保证可以创建多层目录
	    	StringTokenizer s = new StringTokenizer(remote, "/");
	    	s.countTokens(); 
	    	String pathName = ""; 
	    	while (s.hasMoreElements()) { 
	    		   pathName = pathName + "/" + (String) s.nextElement(); 
	    		   try { 
	    			  int i = ftpClient.mkd(pathName); 
	    			  System.out.println(i);
	    		   } catch (Exception e) { 
	    			   logger.info("ftp文件夹创建失败");
	    			   
	    		   } 
	    	}
	    }

	  //判断ftp服务器文件是否存在    
	  public static boolean existFile(String path) throws IOException {
	          boolean flag = false;
	          FTPFile[] ftpFileArr = ftpClient.listFiles(path);
	          if (ftpFileArr.length > 0) {
	              flag = true;
	          }
	          return flag;
	      }
	//改变目录路径
	  public static boolean changeWorkingDirectory(String directory) {
	         boolean flag = true;
	         try {
	             flag = ftpClient.changeWorkingDirectory(directory);
	             if (flag) {
	                 logger.debug("进入文件夹" + directory + " 成功！");

	             } else {
	                 logger.debug("进入文件夹" + directory + " 失败！");
	             }
	         } catch (IOException ioe) {
	             ioe.printStackTrace();
	         }
	         return flag;
	     }


	 //创建目录
	     public static boolean makeDirectory(String dir) {
	         boolean flag = true;
	         try {
	             flag = ftpClient.makeDirectory(dir);
	             if (flag) {
	                 logger.debug("创建文件夹" + dir + " 成功！");

	             } else {
	                 logger.debug("创建文件夹" + dir + " 失败！");
	             }
	         } catch (Exception e) {
	             e.printStackTrace();
	         }
	         return flag;
	     }

	    
}
